import { ruleNodeComponent } from '@/components/ruleNode'
import RuleChainApi from '@/api/ruleChain'
import { NodeType, StageType, NodeConfig } from '@/model/node.model'
import { ProductTypeSimple } from '@/model/product.model'

/**
 * 根据component名称获取
 * @param {*} data
 */
function getRuleNodeComponent(data) {
  return ruleNodeComponent.include(data) ? data : 'unknown'
}

const NodeRemoveBtnArgs = {
  x: '100%',
  offset: {
    x: -6,
    y: 2
  },
  markup: [{
    tagName: 'circle',
    attrs: {
      r: 9,
      fill: '#27282e'
    }
  }]
}

const EdgeRemoveBtnArgs = {
  distance: '50%',
  markup: [{
    tagName: 'circle',
    attrs: {
      r: 7,
      fill: '#27282e'
    }
  }]
}

/**
 * 孤立节点校验
 * 多阶段时，需要针对每个阶段进行判断
 * @param {object} graph 画布对象
 * @param {string} editMode 当前编辑模式
 * @returns 校验结果true/false
 */
function validateNoEdgeNode(graph, editMode) {
  const noIncomingNodes = graph.getRootNodes()
  if (editMode === 'stage') {
    const startNoIncomingNodes = []
    const endNoIncomingNodes = []

    // noIncomingNodes包含阶段区域父节点、并行区域父节点和普通节点
    noIncomingNodes.forEach(node => {
      if (!node.children) {
        // 属于开始阶段的普通节点
        if (node.getParent().id === StageType.startStage) {
          startNoIncomingNodes.push(node)
          return false
        }
        // 属于结束阶段的普通节点
        if (node.getParent().id === StageType.endStage) {
          endNoIncomingNodes.push(node)
          return false
        }
        // 属于开始阶段的并行节点
        if (node.getParent().data.additionalInfo.component === 'AdvancedLibParallelNode' && node.getParent().getParent().id === StageType.startStage) {
          startNoIncomingNodes.push(node)
          return false
        }
        // 属于结束阶段的并行节点
        if (node.getParent().data.additionalInfo.component === 'AdvancedLibParallelNode' && node.getParent().getParent().id === StageType.endStage) {
          endNoIncomingNodes.push(node)
          return false
        }
      }
    })
    return startNoIncomingNodes.length <= 1 && endNoIncomingNodes.length <= 1
  }
  return noIncomingNodes.filter(node => !node.children).length <= 1
}

/**
 * 校验是否存在触发节点
 * 多阶段时，只判断开始阶段是否存在触发节点
 * @param {object} graph 画布对象
 * @param {string} editMode 当前编辑模式
 * @param {object} productInfo 产品基本信息
 * @returns 校验结果
 */
function validateNoTouchNode(graph, editMode, productInfo) {
  const nodes = graph.getNodes()
  const res = { msg: '', result: true }
  const list = []
  if (productInfo.triggerMethod === '1' || productInfo.triggerMethod === '2') { // 主动触发、混合触发产品
    if (!nodes.some(item => item.data?.additionalInfo?.component === 'SceneLibManualTouchNode')) {
      list.push('主动触发')
      res.result = false
    }
    if (editMode === 'stage' && productInfo.voiceCommandEnd && !nodes.some(item => item.data?.additionalInfo?.component === 'SceneLibManualExitNode')) {
      list.push('主动退出')
      res.result = false
    }
  }
  if (productInfo.triggerMethod === '0' || productInfo.triggerMethod === '2') { // 自动触发、混合触发产品
    if (!nodes.some(item => item.data?.additionalInfo?.component === 'SceneLibAutoTouchNode')) {
      list.push('自动触发')
      res.result = false
    }
    // if (editMode === 'stage' && !nodes.some(item => item.data?.additionalInfo?.component === 'SceneLibAutoExitNode')) {
    //   list.push('自动退出')
    //   res.result = false
    // }
  }
  if (res.result === false) {
    res.msg = `规则链缺少${list.join('、')}节点，注意检查`
  }
  return res
}

/**
 * 校验是否存在多余的触发节点
 * @param {object} graph 画布对象
 * @param {object} productInfo 产品基本信息
 * @returns 校验结果
 */
function validateSurplusTouchNode(graph, productInfo) {
  const nodes = graph.getNodes()
  const res = { msg: '', result: true }
  const list = []
  if (productInfo.triggerMethod === '1') { // 主动触发产品
    if (nodes.some(item => item.data?.additionalInfo?.component === 'SceneLibAutoTouchNode')) {
      list.push('自动触发')
      res.result = false
    }
    if (nodes.some(item => item.data?.additionalInfo?.component === 'SceneLibAutoExitNode')) {
      list.push('自动退出')
      res.result = false
    }
    if (nodes.some(item => item.data?.additionalInfo?.component === 'AdvancedLibHistoricalNode')) {
      list.push('历史触发判断')
      res.result = false
    }
  }
  if (productInfo.triggerMethod === '0') { // 自动触发产品
    if (nodes.some(item => item.data?.additionalInfo?.component === 'SceneLibManualTouchNode')) {
      list.push('主动触发')
      res.result = false
    }
    if (nodes.some(item => item.data?.additionalInfo?.component === 'SceneLibManualExitNode')) {
      list.push('主动退出')
      res.result = false
    }
  }
  if (res.result === false) {
    res.msg = `规则链多余${list.join('、')}节点，注意检查`
  }
  return res
}

/**
 * 校验自动触发节点信号重复度
 * @param {object} graph 画布对象
 * @param {string} editMode 当前编辑模式
 * @param {object} productInfo 产品基本信息
 * @returns 校验结果
 */
async function validateAutoTouchNode(graph, productInfo) {
  const nodes = graph.getNodes()
  const res = { msg: [], result: true }
  const keyList = []
  nodes.forEach(node => {
    if (node.data?.additionalInfo?.component === 'SceneLibAutoTouchNode') {
      node.data.configuration?.subScenes.forEach(subscene => {
        subscene.signals.forEach(signal => { keyList.push(signal.signalKey) })
      })
    }
  })
  if (keyList.length) {
    const param = {
      productId: productInfo.basicId,
      modelCodes: productInfo.oemList?.map(item => item.modelCode),
      autoTriggerNodeSignals: keyList
    }
    const res2 = await RuleChainApi.autoTriggerCheck(param)
    if (res2.data.length) {
      res.result = false
      res2.data.forEach(item => { res.msg.push(`与产品 “${item.productName}” 相似度过高，请注意检查`) })
    }
  }
  return res
}

/**
 * 校验语音命令词
 * @param {object} productInfo 产品基本信息
 * @returns 校验结果
 */
async function validateVoiceNode(productInfo) {
  const res = { msg: '', result: true }
  const param = {
    voiceCommands: [],
    modelCode: productInfo.oemList?.map(item => item.modelCode),
    productId: productInfo.basicId
  }
  if (productInfo.voiceCommandStart) { param.voiceCommands.push({ voiceCommand: productInfo.voiceCommandStart, operate: 1 }) }
  if (productInfo.voiceCommandEnd) { param.voiceCommands.push({ voiceCommand: productInfo.voiceCommandEnd, operate: 2 }) }
  if (param.modelCode.length === 0 || productInfo.triggerMethod === '0') return res
  const res2 = await RuleChainApi.voiceCommendCheck(param)
  if (res2.msg) {
    res.result = false
    res.msg = res2.msg
  }
  return res
}

/**
 * 校验是否存在结束节点
 * @param {object} graph 画布对象
 * @returns 校验结果true/false
 */
function validateNoEndNode(graph) {
  return graph.getNodes().some(item => item.data?.additionalInfo?.component === 'AdvancedLibEndNode')
}

/**
 * 空节点校验
 * @desc 仅校验允许编辑且没有子节点的节点。
 *       空节点校验的逻辑采用简化方式，实际上仅针对新的空白节点校验，从网站中创建的节点须由网站自身保证是否为空
 * @param {object} graph 画布对象
 * @returns 返回校验结果，若校验失败，则返回校验失败的节点信息
 */
function validateEmptyNode(graph) {
  const emptyNodeList = graph.getNodes().filter(node => {
    const nodeData = node.getData()
    if (!node.children && nodeData.additionalInfo.editEnabled) {
      const nodeComponent = nodeData.additionalInfo.component
      // 并行结束节点判断count字段是否为空
      if (nodeComponent === 'AdvancedLibParallelEndNode' && (!node.data.configuration || node.data.configuration.count === undefined)) return true
      // 场景库、服务库节点判断信号或者服务列表是否为空
      if (nodeComponent === 'ServiceLibServiceNode' && !(node.data.configuration.serviceSequence)) return true
      if (nodeComponent === 'SceneLibSceneNode' && !(node.data.configuration.subScenes)) return true
      if (!nodeData.configuration) return true
    }
    return false
  })

  return {
    result: !emptyNodeList.length,
    data: emptyNodeList
  }
}

/**
 * 车型匹配校验
 * @param {object} productInfo 产品信息
 * @param {array} supportVehicles 当前产品支持的车型
 * @returns 校验结果true/false
 */
function validateSupportVehicles(productInfo, supportVehicles) {
  if (productInfo.oemList?.length) {
    const productOemList = productInfo.oemList.map(el => el.modelCode)
    const allVehicleModelCode = supportVehicles.map(el => el.modelCode)
    const noMatched = productOemList.find(el => !allVehicleModelCode.includes(el))
    return !noMatched
  }
  return false
}

/**
 * 获取规则链中的全部信号和服务
 * @param {object} graph 画布对象
 * @param {Boolean} optionalFlag 是否过滤掉选装信号
 * @returns
 */
function getRuleChainAllSignalsAndServices(graph, optionalFlag) {
  const allNodes = graph.getNodes()
  // 场景库、自动触发、自动退出、前置节点
  const sceneLibNodes = ['SceneLibSceneNode', 'SceneLibAutoTouchNode', 'SceneLibAutoExitNode', 'SceneLibFrontConditionNode']
  const resData = {
    vehicleSignals: [],
    ecoSignals: [],
    tspSignals: [],
    vehicleServices: [],
    ecoServices: [],
    tspServices: []
  }

  allNodes.forEach(node => {
    const nodeData = node.getData()
    if (node.id !== StageType.startStage && node.id !== StageType.endStage) {
      const nodeComponent = nodeData.additionalInfo?.component
      // 处理场景库
      if (sceneLibNodes.includes(nodeComponent)) {
        if (nodeData.configuration && nodeData.configuration.subScenes?.length) {
          nodeData.configuration.subScenes.forEach(group => {
            group.signals.forEach(signal => {
              if (signal.signalGroup === 'ecoSignal' && !resData.ecoSignals.includes(signal.metaModelId)) {
                resData.ecoSignals.push(String(signal.metaModelId))
              }
              if (signal.signalGroup === 'vehicleSignal' && !resData.vehicleSignals.includes(signal.metaModelId) && (!optionalFlag || signal.optionalFlag === 0)) {
                resData.vehicleSignals.push(String(signal.metaModelId))
              }
              if (signal.signalGroup === 'tspSignal' && !resData.tspSignals.includes(signal.metaModelId)) {
                resData.tspSignals.push(String(signal.metaModelId))
              }
            })
          })
        }
      }
      // 状态变更
      if (nodeComponent === 'AdvancedLibStateChangeNode') {
        if (nodeData.configuration && nodeData.configuration.signals.length) {
          nodeData.configuration.signals.forEach(signal => {
            if (!resData.vehicleSignals.includes(signal.metaModelId)) {
              resData.vehicleSignals.push(String(signal.metaModelId))
            }
          })
        }
      }

      // 处理服务库
      if (nodeComponent === 'ServiceLibServiceNode') {
        if (nodeData.configuration && nodeData.configuration.serviceSequence?.length) {
          nodeData.configuration.serviceSequence.forEach(service => {
            if (!resData.vehicleServices.includes(service.metaModelId)) {
              resData.vehicleServices.push(String(service.metaModelId))
            }
          })
        }
      }
      // 处理弹窗语音交互
      if (['InteractiveLibDialogNode', 'InteractiveLibVoiceNode', 'InteractiveLibDialogVoiceNode'].includes(nodeComponent)) {
        if (nodeData.configuration && nodeData.configuration.metaModelId) {
          const metaModelIds = nodeData.configuration.metaModelId.split('&_&')
          metaModelIds.forEach(item => {
            if (!resData.vehicleServices.includes(item)) { resData.vehicleServices.push(String(item)) }
          })
        }
      }
      // 处理生态服务
      if (nodeComponent === 'ThirdLibThirdNode') {
        if (nodeData.configuration && !resData.ecoServices.includes(nodeData.configuration.metaModelId)) {
          resData.ecoServices.push(String(nodeData.configuration.metaModelId))
        }
      }
      // 处理TSP服务
      if (nodeComponent === 'TspLibTspNode') {
        if (nodeData.configuration && !resData.tspServices.includes(nodeData.configuration.serviceKey)) {
          resData.tspServices.push(String(nodeData.configuration.serviceKey))
        }
      }
    }
  })
  return resData
}

/**
 * 获取规则链中的不包含持续判断的信号，用于车端引擎提前采集相关信息。需要注意区分车端产品和云端产品
 * @param {object} graph 画布对象
 * @param {string} productType 产品类型 车端/云端
 */
function getRuleChainSignals(graph, productType) {
  const allNodes = graph.getNodes()
  const sceneLibNodes = ['SceneLibSceneNode', 'SceneLibAutoTouchNode', 'SceneLibAutoExitNode', 'SceneLibFrontConditionNode']
  const resData = {
    vehicleSignal: [],
    ecologyData: []
  }

  allNodes.forEach(node => {
    const nodeData = node.getData()
    if (node.id !== StageType.startStage && node.id !== StageType.endStage) {
      const nodeComponent = nodeData.additionalInfo?.component
      // 处理场景库
      if (sceneLibNodes.includes(nodeComponent)) {
        if (nodeData.configuration) {
          // 如果是车端产品，则选取未选择持续判断策略的节点
          // 如果是云端产品，则不做限制，因为云端不包含持续判断策略
          if ((productType === 'cloud' && nodeData.configuration.subScenes) || (productType === 'vehicle' && nodeComponent === 'SceneLibSceneNode' && !nodeData.configuration.loopJudgment && nodeData.configuration.subScenes)) {
            nodeData.configuration.subScenes.forEach(group => {
              group.signals.forEach(signal => {
                if (signal.signalGroup === 'ecoSignal' && !resData.ecologyData.includes(signal.signalKey)) {
                  resData.ecologyData.push(String(signal.signalKey))
                }
                if (signal.signalGroup === 'vehicleSignal' && !resData.vehicleSignal.includes(signal.signalKey)) {
                  resData.vehicleSignal.push(String(signal.signalKey))
                }
                // 云端产品的TSP信号放到vehicleSignal中
                if (signal.signalGroup === 'tspSignal' && !resData.vehicleSignal.includes(signal.signalKey)) {
                  resData.vehicleSignal.push(String(signal.signalKey))
                }
              })
            })
          }
        }
      }
    }
  })
  return resData
}

/**
 * 创建阶段画布
 */
function createStageGraph(graph, startNodes = null, endNodes) {
  const wrapper = startNodes ? graph.getCellsBBox(startNodes) : graph.getAllCellsBBox()
  const wrapperWidth = wrapper ? wrapper.width : 0
  const wrapperHeight = wrapper ? wrapper.height : 0
  const wrapperX = wrapper ? wrapper.x : 0
  const wrapperY = wrapper ? wrapper.y : 0
  const wrapperPadding = 30
  const stageNameWidth = 40

  const stageWidth = wrapperWidth + stageNameWidth + wrapperPadding * 2 < graph.options.width - 32 ? graph.options.width - 32 : wrapperWidth + stageNameWidth + wrapperPadding * 2
  let stageHeight = ((wrapperHeight + wrapperPadding * 2 < (graph.options.height - 40 - 80) / 2) && !startNodes) ? (graph.options.height - 40 - 80) / 2 : wrapperHeight + wrapperPadding * 2
  const stageX = wrapperX > 16 ? 16 : wrapperX - stageNameWidth - wrapperPadding * 2
  const stageY = wrapperY - wrapperPadding

  // 结束阶段高度计算
  let endStageY = stageY + stageHeight
  let endStageHeight = stageHeight
  if (endNodes) {
    const wrapper = graph.getCellsBBox(endNodes) || { height: 200, y: endStageY }
    endStageHeight = wrapper.height + wrapperPadding * 2
    // 阶段间剩余空间平均分配
    if (wrapper.y - endStageY > wrapperPadding) {
      const space = (wrapper.y - endStageY - wrapperPadding) / 2
      endStageHeight += space
      endStageY += space
      stageHeight += space
    }
  }

  // 存一下阶段组件信息用于限制子节点移动范围
  window.stageWrapper = { x: stageX, y: stageY, width: stageWidth, height: stageHeight }

  const stageNode = {
    id: '',
    x: stageX,
    y: stageY,
    width: stageWidth,
    height: stageHeight,
    zIndex: 1,
    shape: 'stage-node',
    label: '',
    attrs: {
      'name-rect': {
        height: stageHeight
      }
    },
    data: {
      // 禁止移动
      disableMove: true,
      // 禁止响应相关事件
      preventEvent: true
    }
  }
  const startStageNode = {}
  const endStageNode = {}
  Object.assign(startStageNode, stageNode, {
    id: StageType.startStage,
    label: '开始阶段'
  })
  Object.assign(endStageNode, stageNode, {
    id: StageType.endStage,
    label: '结束阶段',
    height: endStageHeight,
    attrs: {
      'name-rect': {
        height: endStageHeight
      }
    },
    y: endStageY
  })

  const startStage = graph.addNode(startStageNode)
  const endStage = graph.addNode(endStageNode)
  startStage.toBack()
  endStage.toBack()
  return {
    startStage,
    endStage
  }
}

/**
 * 拖拽创建并行节点
 */
function creatParallelNode(graph, node, nextPortId, nextNodeId, editMode) {
  const startparallelNode = graph.getNodes().find(item => item.id === node.id)
  startparallelNode.data.configuration = {}
  startparallelNode.data.configuration.order = nextNodeId
  startparallelNode.data.additionalInfo.parallelOrder = nextNodeId
  const ports = [{ id: (nextPortId++) + '', group: 'in' }, { id: (nextPortId++) + '', group: 'out' }]
  const parallelEndNode = {
    id: `rule-node-${nextNodeId + 1}`,
    x: startparallelNode.position().x + 330,
    y: startparallelNode.position().y,
    zIndex: 100,
    data: {
      name: '并行结束',
      description: '',
      type: 'FLOW_NODE',
      nodeClass: NodeConfig.FLOW_NODE.nodeClass,
      additionalInfo: {
        icon: 'parallelEndNode',
        clazz: 'ParallelGatewayEndNode',
        component: 'AdvancedLibParallelEndNode',
        parallelOrder: nextNodeId,
        editEnabled: true,
        inEnabled: true,
        outEnabled: true,
        relationTypes: ['Success'],
        removeEnabled: true,
        visible: true
      },
      configuration: {
        order: nextNodeId
      }
    },
    ports,
    shape: 'cube-node'
  }
  const parallel = {
    label: '',
    x: startparallelNode.position().x - 30,
    y: startparallelNode.position().y - 30,
    shape: 'parallel-node',
    width: 450,
    height: 120,
    zIndex: 2,
    data: {
      additionalInfo: {
        component: 'AdvancedLibParallelNode',
        parallelOrder: nextNodeId
      }
    }
  }
  const parallelNode = graph.addNode(parallel) // 添加并行父节点
  const endparallelNode = graph.addNode(parallelEndNode)
  parallelNode.addChild(startparallelNode) // 添加并行开始节点
  parallelNode.addChild(endparallelNode) // 添加并行结束节点
  startparallelNode.setParent(parallelNode)
  endparallelNode.setParent(parallelNode)
  if (editMode === 'stage') { // 阶段模式下 并行父节点需要添加阶段作为父节点
    addStageParent(parallelNode, graph)
  }
}

/**
 * 初始化创建并行节点
 */
function initParallelNode(graph, data, editMode) {
  const nodes = data.nodes
  const startparallelNodeList = nodes.filter(item => item.component === 'AdvancedLibParallelStartNode')
  startparallelNodeList.forEach(startparallelNode => {
    const childrenList = nodes.filter(item => item.additionalInfo.parallelOrder === startparallelNode.configuration.order)
    const allParallelNodeList = childrenList.map(item => graph.getNodes().find(Node => Node.data.nodeId === item.nodeId))
    allParallelNodeList.push(graph.getNodes().find(Node => Node.data.nodeId === startparallelNode.nodeId))
    allParallelNodeList.push(graph.getNodes().find(Node => Node.data.additionalInfo.component === 'AdvancedLibParallelEndNode' && Node.data.configuration.order === startparallelNode.configuration.order))
    const wrapper = graph.getCellsBBox(allParallelNodeList)
    const parallel = {
      label: '',
      x: wrapper.x - 30,
      y: wrapper.y - 30,
      shape: 'parallel-node',
      width: wrapper.width + 60,
      height: wrapper.height + 60,
      zIndex: 2,
      data: {
        additionalInfo: {
          component: 'AdvancedLibParallelNode',
          parallelOrder: startparallelNode.configuration.order
        }
      }
    }
    const parallelNode = graph.addNode(parallel) // 添加并行父节点
    allParallelNodeList.forEach(item => { // 添加并行子节点
      parallelNode.addChild(item)
      item.setParent(parallelNode)
    })
    if (editMode === 'stage') { // 阶段模式下 并行父节点需要添加阶段作为父节点
      setTimeout(() => { addStageParent(parallelNode, graph) }, 300)
    }
  })
}

function addStageParent(parallelNode, graph) {
  const bbox = parallelNode.getBBox()
  let stageNode = graph.getNodes().filter((node) => {
    if (node.children && ['start-stage-node', 'end-stage-node'].includes(node.id)) {
      const targetBBox = node.getBBox()
      return bbox.isIntersectWithRect(targetBBox)
    }
    return false
  })[0]
  if (stageNode) { // 保存并行节点所属阶段
    parallelNode.getChildren().forEach(item => {
      graph.isNode(item) && (item.data.additionalInfo.parallelStage = stageNode.id)
    })
  } else { // 读取并行节点所属阶段并设置为父节点
    const endparallelNode = parallelNode.getChildren().find(node => node.data.additionalInfo.component === 'AdvancedLibParallelEndNode')
    stageNode = graph.getNodes().find(node => node.id === endparallelNode.data.additionalInfo.parallelStage)
  }
  const allBBox = graph.getCellsBBox([stageNode, parallelNode])
  stageNode.prop({ position: { x: allBBox.x, y: allBBox.y }, size: { width: allBBox.width, height: allBBox.height } })
  stageNode.addChild(parallelNode)
  parallelNode.setParent(stageNode)
}

/**
 * 基于规则链数据实时修改节点数据
 */
// function adapterNodeByRuleChain(args) {
//   const { graph, productType, editMode, remove } = args
//   const nodes = graph.getNodes()

//   if (productType === ProductTypeSimple.vehicle) {
//     // 如果规则链中包含自动触发节点，则开始节点可以编辑
//     const newStartNodeData = {
//       additionalInfo: {
//         editEnabled: !!nodes.find(node => node.data.additionalInfo?.component === 'SceneLibAutoTouchNode' && (editMode === 'easy' || node._parent?.id === StageType.startStage || node.data?.additionalInfo?.parallelStage === 'start-stage-node'))
//       }
//     }
//     const startNode = nodes.find(node => {
//       if (node.data.type === NodeType.startNode) {
//         return editMode === 'easy' || node.getParent().id === StageType.startStage
//       }
//       return false
//     })

//     // 删除自动触发节点时，需要将开始节点内容清空
//     if (remove) {
//       newStartNodeData.configuration = null
//     }
//     startNode.setData(newStartNodeData)
//   }
// }

/**
 * 基于规则链数据修改最终提交数据
 * 注意：该方法内的所有数据不经过校验
 */
function editRuleChainDataByNode({ ruleChainData, nodes, editMode, graph, productType }) {
  const autoTriggerNodes = []
  const manualTriggerNodes = []

  nodes.forEach((node, index) => {
    const nodeData = node.data

    if (nodeData.type === NodeType.startNode) {
      // 开始阶段的开始节点或简单模式下的开始节点
      if ((editMode === 'stage' && node.getParent().id === StageType.startStage) || editMode === 'easy') {
        ruleChainData.firstNodeIndex = index
        // 扩充开始节点内容
        const extendData = getRuleChainSignals(graph, productType)
        nodeData.configuration = (nodeData.configuration || {})
        Object.assign(nodeData.configuration, extendData)
      }

      // 结束阶段的结束节点
      if (editMode === 'stage' && node.getParent().id === StageType.endStage) {
        ruleChainData.extendData.phaseNodeIndex = index
      }
    }

    // 获取自动触发方式列表
    if (nodeData.additionalInfo.component === 'SceneLibAutoTouchNode') {
      autoTriggerNodes.push(node)
    }
    // 获取主动触发方式列表
    if (nodeData.additionalInfo.component === 'SceneLibManualTouchNode') {
      manualTriggerNodes.push(node)
      // 保存语音命令
      if (nodeData.configuration && !ruleChainData.productDef.voiceCommandList.includes(nodeData.configuration.voiceCommand)) {
        ruleChainData.productDef.voiceCommandList.push(nodeData.configuration.voiceCommand)
      }
    }

    // 如果包含服务恢复节点，则将serviceRecover设置为1
    if (nodeData.additionalInfo.component === 'AdvancedLibServeBackNode') {
      ruleChainData.extendData.serviceRecover = 1
    }

    // 如果包含主动退出节点，则将manualExit设置为1
    if (nodeData.additionalInfo.component === 'SceneLibManualExitNode') {
      ruleChainData.productDef.manualExit = 1
    }

    // 自动、主动触发和自动、主动退出节点的publishEvent取默认值
    if (nodeData.configuration && ['SceneLibAutoTouchNode', 'SceneLibManualTouchNode', 'SceneLibAutoExitNode', 'SceneLibManualExitNode'].includes(nodeData.additionalInfo.component)) {
      nodeData.configuration.publishEvent = nodeData.additionalInfo.defaultConfiguration.publishEvent
    }

    // 弹窗节点后的连接线的connectType需要改为存id
    if (['InteractiveLibDialogNode', 'InteractiveLibVoiceNode', 'InteractiveLibDialogVoiceNode'].includes(nodeData.additionalInfo.component)) {
      const buttons = nodeData.configuration?.inputParams[0].value.buttons || []
      ruleChainData.connections.filter(item => item.sourceNodeIndex === index).forEach(item => {
        item.connectType = buttons.find(button => button.title === item.connectType)?.id || ''
      })
    }
  })

  // 仅有手动时为manual，手自混合是mix，仅有自动为auto，云端产品默认auto
  if (manualTriggerNodes.length || autoTriggerNodes.length) {
    if (!manualTriggerNodes.length) {
      ruleChainData.productDef.executeMode = 'auto'
    } else if (autoTriggerNodes.length) {
      ruleChainData.productDef.executeMode = 'mix'
    } else {
      ruleChainData.productDef.executeMode = 'manual'
    }
  } else if (productType === ProductTypeSimple.cloud) {
    ruleChainData.productDef.executeMode = 'auto'
  }
  return ruleChainData
}

/**
 * 校验画布是否发生修改
 * @param {object} graph 画布对象
 * @param {object} productInfo 产品基本信息
 * @param {object} savedData 上一次保存的数据
 * @returns 校验结果 true有变更
 */
function graphIsChange(graph, productInfo, savedData) {
  if (savedData.graph) {
    const graphData = graph.toJSON()
    if (savedData.graph === JSON.stringify(graphData) && savedData.productInfo === JSON.stringify(productInfo)) {
      return false
    }
  }
  return true
}

export {
  EdgeRemoveBtnArgs,
  NodeRemoveBtnArgs,
  getRuleNodeComponent,
  validateNoEdgeNode,
  validateNoTouchNode,
  validateSurplusTouchNode,
  validateAutoTouchNode,
  validateVoiceNode,
  validateNoEndNode,
  validateEmptyNode,
  validateSupportVehicles,
  getRuleChainSignals,
  getRuleChainAllSignalsAndServices,
  createStageGraph,
  // adapterNodeByRuleChain,
  creatParallelNode,
  initParallelNode,
  editRuleChainDataByNode,
  graphIsChange
}
